glplatform
==========

`glplatform` provides a framework for developing OpenGL applications without taking control over an application's main loop. It handles window creation, event processing, OpenGL context management, and OpenGL binding management. `glplatform` is only designed to make it easy to create an OpenGL application and does not serve as general purpose platform abstraction library. At present only GNU/Linux is supported. Support for other platforms may be added later as variants of the present interface.

Creating a window
-----------------

An window can be created in by calling glplatform_create_window() specifying its title, initial dimentions, and a structure containing event callbacks. The event callbacks will be called inside `glplatform_process_events()` (see below).

Example: Create a "Hello world" window

	void on_key_down(struct glplatform_win *win, int k)
	{
		printf("Key pressed: %c\n", k);
	}

	int main()
	{
		struct glplatform_win_callbacks cb = {
			.on_key_down = on_key_down
		};

		struct glplatform_win *win = glplatform_create_window("Hello window", &cb, 512, 512);
		//...
	}

Event processing
----------------

`glplatform` invokes callbacks for previously queued events when `glplatform_process_events()` is called. Events are queued by `glplatform_get_events()`.

Example: A simple main loop

	int main()
	{
		//...
		while (glplatform_process_events()) {
			if (glplatform_get_events(true) < 0)
				break;
		}
	}

If false is passed into `glplatform_get_events()` then `glplatform` will not block and returns the number of events queued, allowing the user to poll for events. `glplatform` uses `epoll()` to wait for events and it exposes the epoll file descriptor it uses to the application as `glplatform_epoll_fd`. This may allow for `glplatform` event processing to be performed in combination with other event processing systems without polling.

Creating an OpenGL context
--------------------------

When creating a context you must specify which OpenGL version your application requires and the window that the context will be rendering to. The version on the returned context may be higher but will be backwards compatible with the requested version. The returned context will always be a core profile context. Before OpenGL calls can be made the context must be made current with `glplatform_make_current()`. This causes call OpenGL commands on the current thread to operate in the context.

Example: Creating a OpenGL 3.3 core profile compatible context

	struct glplatform_win *win = glplatform_create_window("Hello window", &cb, 512, 512);

	//...

	glplatform_gl_context_t ctx = glplatform_create_context(win, 3, 3);
	if (!ctx)
		exit(-1)

	glplatform_make_current(win, ctx);

Function pointer binding
------------------------

Once a context has been made current OpenGL calls cannot be issued until the OpenGL API's function pointers are bound. `glplatform` contains bindings generated by `glbindify` for this purpose.

Example: Initializing OpenGL bindings

	#include "glplatform.h"
	#include "glplatform-glcore.h"

	int main()
	{
		struct glplatform_win *win;
		glplatform_gl_context_t ctx;

		//...

		glplatform_make_current(win, ctx);

		if (!glplatform_glcore_init(3, 3)) {
			exit(-1);
		}
	}


See the `glbindify` documentation for details. Note that `glplatform` uses the namespace feature of `glbindify` so where the documentation refers to `glb` or `GLB` you should substitute `glplatform` or `GLPLATFORM`
respectively.
